package com.notifier.filter;

import com.notifier.event.ErrorEvent;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 去重过滤器
 * 职责：相同错误签名10分钟内只通过一次
 *
 * @author Amadeus
 * @date 2025/10/14
 */
@Slf4j
@Component
public class DeduplicationFilter implements IErrorFilter {
    
    /** 去重时间窗口：10分钟 */
    private static final long DEDUP_INTERVAL = 10 * 60 * 1000;
    
    /** 错误记录缓存 */
    private static final ConcurrentHashMap<String, ErrorRecord> ERROR_CACHE = new ConcurrentHashMap<>();
    
    @Override
    public boolean shouldFilter(ErrorEvent event) {
        String signature = event.getSignature();
        if (signature == null) {
            return false;  // 没有签名，不过滤
        }
        
        long currentTime = System.currentTimeMillis();
        ErrorRecord record = ERROR_CACHE.get(signature);
        
        if (record != null) {
            long timeSinceLastSent = currentTime - record.getLastSentTime();
            if (timeSinceLastSent < DEDUP_INTERVAL) {
                // 在时间窗口内，增加计数
                int count = record.getCount().incrementAndGet();
                log.debug("重复错误被过滤，签名：{}，重复次数：{}", signature, count);
                return true;  // 过滤掉
            } else {
                // 超过时间窗口，更新最后发送时间
                int skippedCount = record.getCount().getAndSet(0);
                record.setLastSentTime(currentTime);
                
                // 如果有被跳过的次数，附加到消息中
                if (skippedCount > 0) {
                    String originalMsg = event.getFullErrorMessage();
                    String newMsg = "⚠️ 此错误在过去10分钟内重复了 " + skippedCount + " 次\n\n" + originalMsg;
                    event.setFullErrorMessage(newMsg);
                }
                return false;  // 通过
            }
        } else {
            // 首次出现，记录
            ERROR_CACHE.put(signature, new ErrorRecord(currentTime));
            cleanExpiredCache(currentTime);
            return false;  // 通过
        }
    }
    
    @Override
    public int getOrder() {
        return 2;  // 第二优先级
    }
    
    @Override
    public String getName() {
        return "DeduplicationFilter";
    }
    
    /**
     * 清理过期缓存
     */
    private void cleanExpiredCache(long currentTime) {
        if (ERROR_CACHE.size() > 1000) {
            ERROR_CACHE.entrySet().removeIf(entry -> 
                (currentTime - entry.getValue().getLastSentTime()) > DEDUP_INTERVAL * 2
            );
        }
    }
    
    /**
     * 错误记录
     */
    @Data
    private static class ErrorRecord {
        private long lastSentTime;
        private AtomicInteger count;
        
        ErrorRecord(long time) {
            this.lastSentTime = time;
            this.count = new AtomicInteger(0);
        }
    }
}

